Add field `publish` to Cargo.toml
authorJan Likar <likar.jan@gmail.com>
Sat, 23 Jan 2016 21:16:30 +0000 (22:16 +0100)
committerJan Likar <likar.jan@gmail.com>
Tue, 26 Jan 2016 17:48:30 +0000 (18:48 +0100)
Field `publish` set to false can be used to prevent a
package from being accidentally published.

src/cargo/core/manifest.rs
src/cargo/core/package.rs
src/cargo/ops/registry.rs
src/cargo/util/toml.rs
src/doc/manifest.md
tests/test_cargo_publish.rs

index eece77a3b26e62f8937c0c5c270ebd96f5693a7c..5a4a48182b45a38274029b18e9728188fdcb87fd 100644 (file)
@@ -20,6 +20,7 @@ pub struct Manifest {
     include: Vec<String>,
     metadata: ManifestMetadata,
     profiles: Profiles,
+    publish: bool
 }
 
 /// General metadata about a package which is just blindly uploaded to the
@@ -163,7 +164,8 @@ impl Manifest {
                include: Vec<String>,
                links: Option<String>,
                metadata: ManifestMetadata,
-               profiles: Profiles) -> Manifest {
+               profiles: Profiles,
+               publish: bool) -> Manifest {
         Manifest {
             summary: summary,
             targets: targets,
@@ -173,6 +175,7 @@ impl Manifest {
             links: links,
             metadata: metadata,
             profiles: profiles,
+            publish: publish,
         }
     }
 
@@ -187,6 +190,7 @@ impl Manifest {
     pub fn version(&self) -> &Version { self.package_id().version() }
     pub fn warnings(&self) -> &[String] { &self.warnings }
     pub fn profiles(&self) -> &Profiles { &self.profiles }
+    pub fn publish(&self) -> bool { self.publish }
     pub fn links(&self) -> Option<&str> {
         self.links.as_ref().map(|s| &s[..])
     }
index 45242b076c390014a86e2178f76d63cf44e77abe..9aa3c86699c1b94e91840302afa273f8a9e43636 100644 (file)
@@ -79,6 +79,7 @@ impl Package {
     pub fn summary(&self) -> &Summary { self.manifest.summary() }
     pub fn targets(&self) -> &[Target] { self.manifest().targets() }
     pub fn version(&self) -> &Version { self.package_id().version() }
+    pub fn publish(&self) -> bool { self.manifest.publish() }
 
     pub fn has_custom_build(&self) -> bool {
         self.targets().iter().any(|t| t.is_custom_build())
index 3ae68e7095fe5b3d09168b3783c3cf5af6e23fd8..62b287959d26ad677bb9dcd5b0128959cb189ca3 100644 (file)
@@ -34,6 +34,11 @@ pub fn publish(manifest_path: &Path,
                verify: bool) -> CargoResult<()> {
     let pkg = try!(Package::for_path(&manifest_path, config));
 
+    if !pkg.publish() {
+        bail!("some crates cannot be published.\n\
+               `{}` is marked as unpublishable", pkg.name());
+    }
+
     let (mut registry, reg_id) = try!(registry(config, token, index));
     try!(verify_dependencies(&pkg, &reg_id));
 
index 24da8c920e3054bed57286b47135b462473aa4a8..47b67aa0c64a582a170b947b6a6136ed6297dad8 100644 (file)
@@ -254,6 +254,7 @@ pub struct TomlProject {
     links: Option<String>,
     exclude: Option<Vec<String>>,
     include: Option<Vec<String>>,
+    publish: Option<bool>,
 
     // package metadata
     description: Option<String>,
@@ -562,13 +563,15 @@ impl TomlManifest {
             keywords: project.keywords.clone().unwrap_or(Vec::new()),
         };
         let profiles = build_profiles(&self.profile);
+        let publish = project.publish.unwrap_or(true);
         let mut manifest = Manifest::new(summary,
                                          targets,
                                          exclude,
                                          include,
                                          project.links.clone(),
                                          metadata,
-                                         profiles);
+                                         profiles,
+                                         publish);
         if project.license_file.is_some() && project.license.is_some() {
             manifest.add_warning(format!("warning: only one of `license` or \
                                                    `license-file` is necessary"));
index 258ecf9f77e5a09c925a1a69640b295662db43a4..89e900f177c41ae9435f5a9018e0d430c8b05c2d 100644 (file)
@@ -71,6 +71,18 @@ necessary source files may not be included.
 
 [globs]: http://doc.rust-lang.org/glob/glob/struct.Pattern.html
 
+
+## The `publish`  Field (optional)
+
+The `publish` field can be used to prevent a package from being
+published to a repository by mistake.
+
+```toml
+[package]
+# ...
+publish = false
+```
+
 ## Package metadata
 
 There are a number of optional metadata fields also accepted under the
index a30a63f8dd0156e11f4d13e0ad427078e01c7a6c..c985504b67b28103e0be8b2d66f23883b35934e7 100644 (file)
@@ -137,3 +137,23 @@ all path dependencies must have a version specified when publishing.
 dependency `bar` does not specify a version
 "));
 });
+
+test!(unpublishable_crate {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [project]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+            license = "MIT"
+            description = "foo"
+            publish = false
+        "#)
+        .file("src/main.rs", "fn main() {}");
+
+    assert_that(p.cargo_process("publish"),
+                execs().with_status(101).with_stderr("\
+some crates cannot be published.
+`foo` is marked as unpublishable
+"));
+});